package com.service.scheduler.other;

import java.util.Date;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerKey;

import com.service.bean.device.Vehicle;
import com.service.cache.CacheManager;
import com.service.other.Logger;
import com.service.scheduler.job.DutyEndJob;
import com.service.scheduler.job.DutyStartJob;
import com.service.scheduler.sched.DutySched;
import com.service.scheduler.server.SchedulerCreator;
import com.service.scheduler.server.SchedulerServer;

/**
 * 服务器运行时新增、修改车辆排班
 * @author lj
 *
 */
public class AllocateDuty {
	/**
	 * 新增车辆排班, 只新增不更新
	 * @param vehicle
	 * @throws SchedulerException 
	 */
	public void addDuty(Vehicle vehicle) throws SchedulerException {
		Logger.debug(vehicle.device.deviceNo, vehicle.plateNO + "开始新增排班");
		if (null == vehicle || null == vehicle.duty) {
			Logger.debug(vehicle.device.deviceNo, vehicle.plateNO + "新增排班失败, 车辆不存在或者车辆当前无排班");
			return;
		}
		Scheduler sched = CacheManager.instance().schedMap.get(DutySched.class.getSimpleName());
		if (null == sched) {
			sched = SchedulerCreator.createScheduler(DutySched.class.getSimpleName(), 1, Trigger.DEFAULT_PRIORITY);
			CacheManager.instance().schedMap.put(DutySched.class.getSimpleName(), sched);
		}
		addStartDuty(vehicle, sched);
		addEndDuty(vehicle, sched);
	}
	
	/**
	 * 更新车辆排班, 只更新不新增
	 * @param vehicle
	 * @throws Exception 
	 */
	public void updateDuty(Vehicle vehicle) throws Exception {
		Scheduler sched = CacheManager.instance().schedMap.get(DutySched.class.getSimpleName());
		if (null != sched) {
			if (null == vehicle.duty) {
				Logger.debug(vehicle.device.deviceNo, vehicle.plateNO + "车辆当前无排班, 准备删除已有定时器");
				// 删除上班检查定时器
				JobKey startJobKey = JobKey.jobKey("start_" + vehicle.device.deviceNo, "workstart");
				TriggerKey startTriggerKey = TriggerKey.triggerKey("start_" + vehicle.device.deviceNo, "workstart");
				sched.pauseTrigger(startTriggerKey);
				sched.unscheduleJob(startTriggerKey);
				sched.deleteJob(startJobKey);
				// 删除下班检查定时器
				JobKey endJobKey = JobKey.jobKey("end_" + vehicle.device.deviceNo, "workend");
				TriggerKey endTriggerKey = TriggerKey.triggerKey("end_" + vehicle.device.deviceNo, "workend");
				sched.pauseTrigger(endTriggerKey);
				sched.unscheduleJob(endTriggerKey);
				sched.deleteJob(endJobKey);
				Logger.debug(vehicle.device.deviceNo, vehicle.plateNO + "定时器删除完毕");
			} else {
				updateStartDuty(vehicle, sched);
				updateEndDuty(vehicle, sched);
			}
		} else {
			Logger.debug(vehicle.device.deviceNo, vehicle.plateNO + "当前无定时器存在, 更新失败, 准备新增上下班检查定时器");
			sched = SchedulerCreator.createScheduler(DutySched.class.getSimpleName(), 1, Trigger.DEFAULT_PRIORITY);
			CacheManager.instance().schedMap.put(DutySched.class.getSimpleName(), sched);
			addStartDuty(vehicle, sched);
			addEndDuty(vehicle, sched);
		}
	}
	
	/**
	 * 新增车辆上班定时器
	 * @param vehicle
	 * @param sched
	 * @throws SchedulerException
	 */
	private void addStartDuty(Vehicle vehicle, Scheduler sched) throws SchedulerException {
		Date date = null;
		if (0 == vehicle.duty.startFloatTime) {
			date = new Date(vehicle.duty.workStartTime.getTime() + 1 * 60 * 1000);
		} else {
			date = new Date(vehicle.duty.workStartTime.getTime() + vehicle.duty.startFloatTime * 60 * 1000);
		}
		String cronExp = SchedulerCreator.createCronExpr(date);
		JobKey jobKey = JobKey.jobKey("start_" + vehicle.device.deviceNo, "workstart");
		TriggerKey triggerKey = TriggerKey.triggerKey("start_" + vehicle.device.deviceNo, "workstart");
		JobDetail job = SchedulerCreator.createJob(jobKey, DutyStartJob.class);
		job.getJobDataMap().put("gpsno", vehicle.device.deviceNo);
		CronTrigger trigger = SchedulerCreator.createCronTriggerForJob(job, triggerKey, cronExp);
		if (sched.checkExists(triggerKey)) {
			Logger.debug(vehicle.device.deviceNo, "车辆: " + vehicle.plateNO + "新增上班检查定时器失败, 准备删除已存在的定时器, at:" + date);
			sched.pauseTrigger(triggerKey);
			sched.unscheduleJob(triggerKey);
			sched.deleteJob(jobKey);
		}
		sched.scheduleJob(job, trigger);
		Logger.debug(vehicle.device.deviceNo, "车辆: " + vehicle.plateNO + "新增上班检查定时器成功, at:" + date);
	}
	
	/**
	 * 新增车辆下班定时器
	 * @param vehicle
	 * @param sched
	 * @throws SchedulerException
	 */
	private void addEndDuty(Vehicle vehicle, Scheduler sched) throws SchedulerException {
		Date date = null;
		if (0 == vehicle.duty.endFloatTime) {
			date = new Date(vehicle.duty.workEndTime.getTime() + 1 * 60 * 1000);
		} else {
			date = new Date(vehicle.duty.workEndTime.getTime() + vehicle.duty.endFloatTime * 60 * 1000);
		}
		String cronExp = SchedulerCreator.createCronExpr(date);
		JobKey jobKey = JobKey.jobKey("end_" + vehicle.device.deviceNo, "workend");
		TriggerKey triggerKey = TriggerKey.triggerKey("end_" + vehicle.device.deviceNo, "workend");
		JobDetail job = SchedulerCreator.createJob(jobKey, DutyEndJob.class);
		job.getJobDataMap().put("gpsno", vehicle.device.deviceNo);
		CronTrigger trigger = SchedulerCreator.createCronTriggerForJob(job, triggerKey, cronExp);
		if (sched.checkExists(triggerKey)) {
			Logger.debug(vehicle.device.deviceNo, "车辆: " + vehicle.plateNO + "新增下班检查定时器失败, 准备删除已存在的定时器, at:" + date);
			sched.pauseTrigger(triggerKey);
			sched.unscheduleJob(triggerKey);
			sched.deleteJob(jobKey);
		}
		sched.scheduleJob(job, trigger);
		Logger.debug(vehicle.device.deviceNo, "车辆: " + vehicle.plateNO + "新增下班检查定时器成功, at:" + date);
	}
	
	/**
	 * 更新车辆上班定时器, 在执行该方法前需要刷新车辆排班</br>
	 * 只更新, 不新增
	 * @param vehicle
	 * @param sched
	 */
	private void updateStartDuty(Vehicle vehicle, Scheduler sched) throws Exception {
		
		Logger.debug(vehicle.device.deviceNo, "开始更新车辆上班定时器");
		Date date = null;
		if (0 == vehicle.duty.startFloatTime) {
			date = new Date(vehicle.duty.workStartTime.getTime() + 1 * 60 * 1000);
		} else {
			date = new Date(vehicle.duty.workStartTime.getTime() + vehicle.duty.startFloatTime * 60 * 1000);
		}
		JobKey jobKey = JobKey.jobKey("start_" + vehicle.device.deviceNo, "workstart");
		JobDetail job = SchedulerCreator.createJob(jobKey, DutyStartJob.class);
		job.getJobDataMap().put("gpsno", vehicle.device.deviceNo);
		String cronExp = SchedulerCreator.createCronExpr(date);
		boolean flag = SchedulerServer.instance().rescheduleJob(
				DutySched.class.getSimpleName(), jobKey.getName(), jobKey.getGroup(), cronExp);
		if (flag) {
			Logger.debug(vehicle.device.deviceNo, vehicle.plateNO + "更新上班排班成功");
		} else {
			Logger.debug(vehicle.device.deviceNo, vehicle.plateNO + "更新上班排班失败");
		}
		
	}
	
	/**
	 * 更新车辆下班定时器, 在执行该方法前需要刷新车辆排班
	 * @param vehicle
	 * @param sched
	 */
	private void updateEndDuty(Vehicle vehicle, Scheduler sched) throws Exception {
		
		Logger.debug(vehicle.device.deviceNo, vehicle.plateNO + "开始更新车辆下班定时器");
		Date date = null;
		if (0 == vehicle.duty.endFloatTime) {
			date = new Date(vehicle.duty.workEndTime.getTime() + 1 * 60 * 1000);
		} else {
			date = new Date(vehicle.duty.workEndTime.getTime() + vehicle.duty.endFloatTime * 60 * 1000);
		}
		JobKey jobKey = JobKey.jobKey("end_" + vehicle.device.deviceNo, "workend");
		JobDetail job = SchedulerCreator.createJob(jobKey, DutyEndJob.class);
		job.getJobDataMap().put("gpsno", vehicle.device.deviceNo);
		String cronExp = SchedulerCreator.createCronExpr(date);
		boolean flag = SchedulerServer.instance().rescheduleJob(
				DutySched.class.getSimpleName(), jobKey.getName(), jobKey.getGroup(), cronExp);
		if (flag) {
			Logger.debug(vehicle.device.deviceNo, vehicle.plateNO + "更新下班排班成功");
		} else {
			Logger.debug(vehicle.device.deviceNo, vehicle.plateNO + "更新下班排班失败");
		}
		
	}
	
}
